# 标签打印功能视图
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, permission_required
from django.http import JsonResponse, HttpResponse
from django.views.decorators.http import require_http_methods
from django.contrib import messages
from django.core.paginator import Paginator
from django.db.models import Q
from django.utils import timezone
from django.db import IntegrityError
from datetime import timedelta
import json
import logging
import base64
from io import BytesIO

from .models import Asset
from .models_label import LabelTemplate, LabelPrintJob, PrinterConfiguration, LabelPrintHistory
from .label_printer_service import label_printer_service

logger = logging.getLogger(__name__)


@login_required
def label_templates(request):
    """标签模板管理"""
    
    # 获取筛选参数
    label_size = request.GET.get('size', '')
    search = request.GET.get('search', '')
    
    # 构建查询
    templates = LabelTemplate.objects.filter(
        Q(created_by=request.user) | Q(shared_users=request.user) | Q(is_public=True)
    ).distinct()
    
    if label_size:
        templates = templates.filter(label_size=label_size)
    
    if search:
        templates = templates.filter(
            Q(name__icontains=search) | Q(description__icontains=search)
        )
    
    templates = templates.order_by('-updated_at')
    
    # 分页
    paginator = Paginator(templates, 12)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    context = {
        'page_obj': page_obj,
        'label_sizes': LabelTemplate.LABEL_SIZE_CHOICES,
        'current_filters': {
            'size': label_size,
            'search': search,
        }
    }
    
    return render(request, 'assets/label/templates.html', context)


@login_required
@permission_required('assets.add_labeltemplate', raise_exception=True)
def label_template_designer(request):
    """标签模板设计器"""
    
    template_id = request.GET.get('template_id')
    template = None
    
    if template_id:
        try:
            template = LabelTemplate.objects.get(id=template_id)
            # 检查权限
            if not (template.created_by == request.user or 
                   request.user in template.shared_users.all() or 
                   template.is_public):
                messages.error(request, '没有权限编辑此模板')
                return redirect('assets:label_template_list')
        except LabelTemplate.DoesNotExist:
            messages.error(request, '标签模板不存在')
            return redirect('assets:label_template_list')
    
    # 获取可用字段
    available_fields = []
    if template:
        available_fields = template.get_available_fields()
    else:
        # 创建临时模板获取字段
        temp_template = LabelTemplate()
        available_fields = temp_template.get_available_fields()
    
    context = {
        'template': template,
        'available_fields': json.dumps(available_fields),
        'label_sizes': LabelTemplate.LABEL_SIZE_CHOICES,
        'printer_models': LabelTemplate.PRINTER_MODEL_CHOICES,
    }
    
    return render(request, 'assets/pt9500pc_modern.html', context)


@login_required
@permission_required('assets.add_labeltemplate', raise_exception=True)
@require_http_methods(["POST"])
def save_label_template(request):
    """保存标签模板"""
    
    try:
        data = json.loads(request.body)
        
        template_id = data.get('template_id')
        name = data.get('name')
        description = data.get('description', '')
        label_width = data.get('label_width', '18mm')
        orientation = data.get('orientation', 'portrait')
        font_size = data.get('font_size', 'medium')
        printer_model = data.get('printer_model', 'pt-9500pc')
        
        # 基本信息字段
        company_header = data.get('company_header', '')
        lost_notice = data.get('lost_notice', '')
        
        # Brother PT-9500PC 特定字段
        include_qr = data.get('include_qr', False)
        include_name = data.get('include_name', False)
        include_number = data.get('include_number', False)
        include_category = data.get('include_category', False)
        include_department = data.get('include_department', False)
        include_user = data.get('include_user', False)
        include_location = data.get('include_location', False)
        include_purchase_date = data.get('include_purchase_date', False)
        include_warranty = data.get('include_warranty', False)
        include_serial_number = data.get('include_serial_number', False)
        include_status = data.get('include_status', False)
        include_value = data.get('include_value', False)
        
        # 自定义字段
        custom_fields = data.get('custom_fields', [])
        
        is_public = data.get('is_public', False)
        
        # 构建字段配置
        fields_config = {
            'include_qr': include_qr,
            'include_name': include_name,
            'include_number': include_number,
            'include_category': include_category,
            'include_department': include_department,
            'include_user': include_user,
            'include_location': include_location,
            'include_purchase_date': include_purchase_date,
            'include_warranty': include_warranty,
            'include_serial_number': include_serial_number,
            'include_status': include_status,
            'include_value': include_value,
            'company_header': company_header,
            'lost_notice': lost_notice,
            'custom_fields': custom_fields
        }
        
        # 构建打印设置
        print_settings = {
            'orientation': orientation,
            'font_size': font_size,
            'label_width': label_width
        }
        
        if not all([name, label_width]):
            return JsonResponse({
                'success': False,
                'message': '缺少必要参数'
            }, status=400)
        
        if template_id:
            # 更新现有模板
            template = get_object_or_404(LabelTemplate, id=template_id)

            # 重名检查（同一用户下不允许同名，排除自身）
            if LabelTemplate.objects.filter(name=name, created_by=request.user).exclude(id=template.id).exists():
                return JsonResponse({
                    'success': False,
                    'code': 'name_conflict',
                    'message': '已存在同名的标签模板，请更换名称'
                }, status=409)
            
            # 检查权限
            if template.created_by != request.user:
                return JsonResponse({
                    'success': False,
                    'message': '没有权限编辑此模板'
                }, status=403)
            
            template.name = name
            template.description = description
            template.label_size = label_width
            template.printer_model = printer_model
            template.fields_config = fields_config
            template.print_settings = print_settings
            template.is_public = is_public
            try:
                template.save()
            except IntegrityError:
                return JsonResponse({
                    'success': False,
                    'code': 'name_conflict',
                    'message': '已存在同名的标签模板，请更换名称'
                }, status=409)
            
            message = '标签模板更新成功'
        else:
            # 创建新模板前重名检查（同一用户）
            if LabelTemplate.objects.filter(name=name, created_by=request.user).exists():
                return JsonResponse({
                    'success': False,
                    'code': 'name_conflict',
                    'message': '已存在同名的标签模板，请更换名称'
                }, status=409)

            # 创建新模板
            try:
                template = LabelTemplate.objects.create(
                    name=name,
                    description=description,
                    label_size=label_width,
                    printer_model=printer_model,
                    fields_config=fields_config,
                    print_settings=print_settings,
                    is_public=is_public,
                    created_by=request.user
                )
            except IntegrityError:
                return JsonResponse({
                    'success': False,
                    'code': 'name_conflict',
                    'message': '已存在同名的标签模板，请更换名称'
                }, status=409)
            
            message = '标签模板创建成功'
        
        return JsonResponse({
            'success': True,
            'message': message,
            'template_id': template.id
        })
        
    except Exception as e:
        logger.error(f"保存标签模板失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'保存失败: {str(e)}'
        }, status=500)


@login_required
@require_http_methods(["POST"])
def preview_label(request):
    """预览标签"""
    
    try:
        data = json.loads(request.body)
        
        template_id = data.get('template_id')
        asset_id = data.get('asset_id')
        custom_data = data.get('custom_data', {})
        
        # 获取模板
        if template_id:
            template = get_object_or_404(LabelTemplate, id=template_id)
        else:
            # 无模板，使用传入的尺寸进行预览
            template = None
            label_size = data.get('label_size', '24mm')
        
        asset = None
        if asset_id:
            asset = get_object_or_404(Asset, id=asset_id)
        
        # Brother PT-9500PC 特定预览设置
        preview_settings = {
            'printer_model': 'PT-9500PC',
            'dpi': 360,  # Brother PT-9500PC 支持360dpi高分辨率
            'label_size': label_size if 'label_size' in locals() else getattr(template, 'label_size', '24mm'),
            'render_quality': 'high',
            'show_cut_lines': True,  # 显示切割线
            'background_color': '#ffffff',
            'border_style': 'none'  # PT-9500PC 不需要边框
        }
        
        # 根据标签尺寸调整预览参数
        size_configs = {
            '6mm': {'width': 48, 'height': 200, 'font_scale': 0.6},
            '9mm': {'width': 72, 'height': 200, 'font_scale': 0.7},
            '12mm': {'width': 96, 'height': 200, 'font_scale': 0.8},
            '18mm': {'width': 144, 'height': 200, 'font_scale': 0.9},
            '24mm': {'width': 192, 'height': 200, 'font_scale': 1.0},
            '36mm': {'width': 288, 'height': 200, 'font_scale': 1.2}
        }
        
        label_size = label_size if 'label_size' in locals() else getattr(template, 'label_size', '24mm')
        if label_size in size_configs:
            preview_settings.update(size_configs[label_size])
        
        # 生成Brother PT-9500PC优化的标签预览图像
        label_image = label_printer_service.create_brother_pt9500pc_preview(
            template, asset, custom_data, preview_settings
        )
        
        # 转换为base64
        buffer = BytesIO()
        label_image.save(buffer, format='PNG', dpi=(360, 360))
        image_data = base64.b64encode(buffer.getvalue()).decode()
        
        return JsonResponse({
            'success': True,
            'image_data': f'data:image/png;base64,{image_data}',
            'width': label_image.width,
            'height': label_image.height,
            'printer_model': 'Brother PT-9500PC',
            'label_size': label_size,
            'dpi': 360
        })
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@login_required
def print_labels_page(request):
    """标签打印页面"""
    
    # 获取可用模板
    templates = LabelTemplate.objects.filter(
        Q(created_by=request.user) | Q(shared_users=request.user) | Q(is_public=True),
        is_active=True
    ).distinct()
    
    # 获取最近的打印任务
    recent_jobs = LabelPrintJob.objects.filter(
        created_by=request.user
    ).order_by('-created_at')[:10]
    
    context = {
        'templates': templates,
        'recent_jobs': recent_jobs,
    }
    
    return render(request, 'assets/label/print.html', context)


@login_required
@require_http_methods(["POST"])
def create_print_job(request):
    """创建打印任务"""
    
    try:
        data = json.loads(request.body)
        
        template_id = data.get('template_id')
        asset_ids = data.get('asset_ids', [])
        print_settings = data.get('print_settings', {})
        
        # 验证模板权限
        template = get_object_or_404(LabelTemplate, id=template_id)
        if not (template.created_by == request.user or 
                template.shared_users.filter(id=request.user.id).exists() or 
                template.is_public):
            return JsonResponse({'success': False, 'message': '无权限使用此模板'})
        
        # 验证资产存在性
        assets = Asset.objects.filter(id__in=asset_ids)
        if len(assets) != len(asset_ids):
            return JsonResponse({'success': False, 'message': '部分资产不存在'})
        
        # Brother PT-9500PC 特定设置验证和优化
        brother_settings = {
            'printer_model': 'PT-9500PC',
            'print_quality': print_settings.get('quality', '360dpi'),
            'label_type': print_settings.get('label_type', 'precut'),
            'cut_each': print_settings.get('cut_each', True),
            'mirror_print': print_settings.get('mirror_print', False),
            'copies': min(int(print_settings.get('copies', 1)), 10),
            'print_speed': print_settings.get('speed', 'normal'),
            'density': print_settings.get('density', 'normal')
        }
        
        # 根据标签尺寸调整打印参数
        label_size = template.label_size
        if label_size in ['6mm', '9mm']:
            brother_settings['print_speed'] = 'slow'  # 小尺寸标签使用慢速打印
        elif label_size in ['24mm', '36mm']:
            brother_settings['density'] = 'high'  # 大尺寸标签使用高密度
        
        # 创建打印任务（使用 JSON 字段保存资产ID 列表）
        print_job = LabelPrintJob.objects.create(
            template=template,
            created_by=request.user,
            print_settings=brother_settings,
            copies=int(brother_settings.get('copies', 1)) or 1,
            asset_ids=list(asset_ids),
            status='pending'
        )

        # 调用打印服务
        result = label_printer_service.print_labels(print_job)
        
        return JsonResponse({
            'success': True,
            'job_id': print_job.id,
            'result': result,
            'printer_settings': brother_settings
        })
        
    except Exception as e:
        logger.error(f"创建打印任务失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'创建失败: {str(e)}'
        }, status=500)


@login_required
def print_job_status(request, job_id):
    """获取打印任务状态"""
    
    try:
        job = get_object_or_404(LabelPrintJob, id=job_id, created_by=request.user)
        
        return JsonResponse({
            'success': True,
            'job': {
                'id': job.id,
                'status': job.status,
                'total_labels': job.total_labels,
                'printed_labels': job.printed_labels,
                'failed_labels': job.failed_labels,
                'success_rate': job.success_rate,
                'error_message': job.error_message,
                'created_at': job.created_at.isoformat(),
                'started_at': job.started_at.isoformat() if job.started_at else None,
                'completed_at': job.completed_at.isoformat() if job.completed_at else None,
            }
        })
        
    except Exception as e:
        logger.error(f"获取打印任务状态失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'获取状态失败: {str(e)}'
        }, status=500)


@login_required
def printer_configurations(request):
    """打印机配置管理"""
    
    configs = PrinterConfiguration.objects.filter(
        created_by=request.user
    ).order_by('-updated_at')
    
    context = {
        'configs': configs,
        'connection_types': PrinterConfiguration.CONNECTION_TYPE_CHOICES,
    }
    
    return render(request, 'assets/label/printer_config.html', context)


@login_required
@permission_required('assets.add_printerconfiguration', raise_exception=True)
@require_http_methods(["POST"])
def save_printer_config(request):
    """保存打印机配置"""
    
    try:
        data = json.loads(request.body)
        
        config_id = data.get('config_id')
        name = data.get('name')
        printer_model = data.get('printer_model', 'pt-9500pc')
        connection_type = data.get('connection_type')
        connection_params = data.get('connection_params', {})
        default_settings = data.get('default_settings', {})
        is_default = data.get('is_default', False)
        
        if not all([name, connection_type]):
            return JsonResponse({
                'success': False,
                'message': '缺少必要参数'
            }, status=400)
        
        if config_id:
            # 更新现有配置
            config = get_object_or_404(PrinterConfiguration, id=config_id, created_by=request.user)
            config.name = name
            config.printer_model = printer_model
            config.connection_type = connection_type
            config.connection_params = connection_params
            config.default_settings = default_settings
            config.is_default = is_default
            config.save()
            
            message = '打印机配置更新成功'
        else:
            # 创建新配置
            config = PrinterConfiguration.objects.create(
                name=name,
                printer_model=printer_model,
                connection_type=connection_type,
                connection_params=connection_params,
                default_settings=default_settings,
                is_default=is_default,
                created_by=request.user
            )
            
            message = '打印机配置创建成功'
        
        return JsonResponse({
            'success': True,
            'message': message,
            'config_id': config.id
        })
        
    except Exception as e:
        logger.error(f"保存打印机配置失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'保存失败: {str(e)}'
        }, status=500)


@login_required
@require_http_methods(["POST"])
def test_printer_connection(request, config_id):
    """测试打印机连接"""
    
    try:
        config = get_object_or_404(PrinterConfiguration, id=config_id, created_by=request.user)
        
        result = label_printer_service.test_printer_connection(config)
        
        return JsonResponse(result)
        
    except Exception as e:
        logger.error(f"测试打印机连接失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'测试失败: {str(e)}'
        }, status=500)


@login_required
def print_history(request):
    """打印历史"""
    
    # 获取筛选参数
    status = request.GET.get('status', '')
    template_id = request.GET.get('template', '')
    date_range = request.GET.get('date_range', '7')
    
    # 计算时间范围
    end_date = timezone.now()
    start_date = end_date - timedelta(days=int(date_range))
    
    # 构建查询
    jobs = LabelPrintJob.objects.filter(
        created_by=request.user,
        created_at__range=[start_date, end_date]
    )
    
    if status:
        jobs = jobs.filter(status=status)
    
    if template_id:
        jobs = jobs.filter(template_id=template_id)
    
    jobs = jobs.order_by('-created_at')
    
    # 分页
    paginator = Paginator(jobs, 20)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    
    # 获取模板列表用于筛选
    templates = LabelTemplate.objects.filter(
        Q(created_by=request.user) | Q(shared_users=request.user) | Q(is_public=True)
    ).distinct()
    
    context = {
        'page_obj': page_obj,
        'templates': templates,
        'status_choices': LabelPrintJob.STATUS_CHOICES,
        'current_filters': {
            'status': status,
            'template': template_id,
            'date_range': date_range,
        }
    }
    
    return render(request, 'assets/label/history.html', context)


@login_required
@require_http_methods(["POST"])
def delete_label_template(request, template_id):
    """删除标签模板"""
    
    try:
        template = get_object_or_404(LabelTemplate, id=template_id)
        
        # 检查权限
        if template.created_by != request.user:
            return JsonResponse({
                'success': False,
                'message': '没有权限删除此模板'
            }, status=403)
        
        # 无默认模板字段，直接允许删除（如需保护逻辑，可基于其他条件判断）
        
        # 检查是否有正在进行的打印任务使用此模板
        active_jobs = LabelPrintJob.objects.filter(
            template=template,
            status__in=['pending', 'processing']
        ).count()
        
        if active_jobs > 0:
            return JsonResponse({
                'success': False,
                'message': f'有 {active_jobs} 个打印任务正在使用此模板，无法删除'
            }, status=400)
        
        template_name = template.name
        template.delete()
        
        return JsonResponse({
            'success': True,
            'message': f'模板 "{template_name}" 删除成功'
        })
        
    except Exception as e:
        logger.error(f"删除标签模板失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'删除失败: {str(e)}'
        }, status=500)


@login_required
@require_http_methods(["POST"])
def duplicate_label_template(request, template_id):
    """复制标签模板"""
    
    try:
        original_template = get_object_or_404(LabelTemplate, id=template_id)
        
        # 检查权限
        if not (original_template.created_by == request.user or 
                original_template.shared_users.filter(id=request.user.id).exists() or 
                original_template.is_public):
            return JsonResponse({
                'success': False,
                'message': '没有权限复制此模板'
            }, status=403)
        
        # 创建副本
        new_template = LabelTemplate.objects.create(
            name=f"{original_template.name} - 副本",
            description=original_template.description,
            label_size=original_template.label_size,
            printer_model=original_template.printer_model,
            fields_config=original_template.fields_config,
            template_design=original_template.template_design,
            print_settings=original_template.print_settings,
            is_public=False,  # 副本默认为私有
            created_by=request.user
        )
        
        return JsonResponse({
            'success': True,
            'message': f'模板 "{original_template.name}" 复制成功',
            'template_id': new_template.id,
            'template_name': new_template.name
        })
        
    except Exception as e:
        logger.error(f"复制标签模板失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'复制失败: {str(e)}'
        }, status=500)


@login_required
def export_label_templates(request):
    """导出标签模板"""
    
    try:
        format_type = request.GET.get('format', 'json')
        range_type = request.GET.get('range', 'user')
        include_preview = request.GET.get('include_preview', 'false') == 'true'
        
        # 构建查询
        if range_type == 'all':
            templates = LabelTemplate.objects.filter(is_public=True)
        else:
            templates = LabelTemplate.objects.filter(
                Q(created_by=request.user) | Q(shared_users=request.user) | Q(is_public=True)
            ).distinct()
        
        # 构建导出数据
        export_data = []
        for template in templates:
            template_data = {
                'name': template.name,
                'description': template.description,
                'label_size': template.label_size,
                'printer_model': template.printer_model,
                'fields_config': template.fields_config,
                'template_design': template.template_design,
                'print_settings': template.print_settings,
                'is_public': template.is_public,
                'created_at': template.created_at.isoformat(),
                'updated_at': template.updated_at.isoformat()
            }
            
            if include_preview:
                # 生成预览图片（简化版）
                template_data['preview'] = f"_placeholder"
            
            export_data.append(template_data)
        
        if format_type == 'json':
            response = JsonResponse({
                'success': True,
                'templates': export_data,
                'count': len(export_data),
                'exported_at': timezone.now().isoformat()
            })
            response['Content-Disposition'] = 'attachment; filename="label_templates.json"'
            return response
        else:
            return JsonResponse({
                'success': False,
                'message': '不支持的导出格式'
            }, status=400)
        
    except Exception as e:
        logger.error(f"导出标签模板失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'导出失败: {str(e)}'
        }, status=500)


@login_required
def get_asset_selector_data(request):
    """获取资产选择器数据"""
    
    try:
        search = request.GET.get('search', '')
        category_id = request.GET.get('category')
        department_id = request.GET.get('department')
        
        # 构建查询
        assets = Asset.objects.all()
        
        if search:
            assets = assets.filter(
                Q(asset_number__icontains=search) |
                Q(name__icontains=search)
            )
        
        if category_id:
            assets = assets.filter(category_id=category_id)
        
        if department_id:
            assets = assets.filter(department_id=department_id)
        
        # 限制结果数量
        assets = assets[:50]
        
        # 构建返回数据
        asset_data = []
        for asset in assets:
            asset_data.append({
                'id': asset.id,
                'asset_number': asset.asset_number,
                'name': asset.name,
                'category': asset.category.name if asset.category else '',
                'department': asset.department.name if asset.department else '',
                'status': asset.get_status_display(),
                'location': asset.location or ''
            })
        
        return JsonResponse({
            'success': True,
            'assets': asset_data
        })
        
    except Exception as e:
        logger.error(f"获取资产选择器数据失败: {e}")
        return JsonResponse({
            'success': False,
            'message': f'获取数据失败: {str(e)}'
        }, status=500)